import { SearchOutlined } from '@ant-design/icons'
import { useRefValue, useThrottle } from '@gnlab/utils/env-react'
import { Input, Button, Tag, Select } from 'antd'
import { ImportantEditModal, Loading } from '@/desktop/components'
import  defaultAvatar  from '@/desktop/assets/avatar.jpg'
import AnyTransfer from './AnyTransfer'
import type { AccountQywx, SearchTag, FullSearchContact } from './logic'
import { useSearch, AccountQywxStatus } from './logic'
import './index.module.less'

export function FullSearch(props: {
  visible: boolean
  initialKeyword: string
  onClose: (hasChoosed: boolean) => void
}) {
  const { visible, onClose, initialKeyword } = props

  return <ImportantEditModal
    open={visible}
    onCancel={() => onClose(false)}
    title="搜索全量客户"
    width="900px"
  >
    <Content initialKeyword={initialKeyword} onClose={onClose} />
  </ImportantEditModal>
}

function Content(props: { initialKeyword: string; onClose: (hasChoosed: boolean) => void }) {
  const { initialKeyword, onClose } = props

  const {
    qywxs,
    tags,
    conditions,
    setKeyword,
    setWxid,
    setTagId,
    loading,
    full,
    nextPage,
    contacts,
  } = useSearch(initialKeyword)

  const qywxMap = useMemo(() => new Map((qywxs ?? []).map(qywx => [qywx.wxid, qywx])), [qywxs])

  const loadingInfoRef = useRefValue({ loading, full })
  const contactsElementRef = useRef<HTMLDivElement>(null)
  const handleScroll = useCallback(() => {
    const { loading, full } = loadingInfoRef.current
    if (loading || full || !contactsElementRef.current) return
    const { offsetHeight, scrollHeight, scrollTop } = contactsElementRef.current
    if (scrollHeight - (scrollTop + offsetHeight) < offsetHeight) void nextPage() // 只要待展示的区域小于一屏了，就触发加载
  }, [nextPage])

  const throttledHandleScroll = useThrottle(handleScroll, 500)

  // 应对内容长度变化而需要加载后续内容的情况，每秒钟固定检查一次
  useEffect(() => {
    const intervalId = setInterval(handleScroll, 1000)
    return () => clearInterval(intervalId)
  }, [handleScroll])

  const [transfering, setTransfering] = useState<{
    contact: FullSearchContact
    qywx: AccountQywx
  } | null>(null)
  function transferFinish(confirmed: boolean) {
    if (confirmed) onClose(true)
    else setTransfering(null)
  }

  return <div styleName="full-search">
    <header styleName="conditions">
      <Input
        size="large"
        prefix={<SearchOutlined />}
        placeholder="输入搜索关键词"
        defaultValue={initialKeyword}
        onChange={e => void setKeyword(e.target.value)}
      />
      <div styleName="extra">
        <label>
          企业微信：
          <QywxSelect qywxs={qywxs} value={conditions.wxid} onChange={setWxid} />
        </label>
        <label>
          标签：
          <TagSelect tags={tags} value={conditions.tagId} onChange={setTagId} />
        </label>
      </div>
    </header>

    <main styleName="contacts" onScroll={throttledHandleScroll} ref={contactsElementRef}>
      {contacts.map(contact => {
        const qywx = qywxMap.get(contact.ownerWxid)
        if (!qywx) return null
        const startTransfer = () => setTransfering({ contact, qywx })
        return <SearchContact
          key={contact.id}
          contact={contact}
          qywx={qywx}
          startTransfer={startTransfer}
        />
      })}

      {loading ? <Loading /> : null}

      {!conditions.keyword ? <div styleName="tips">请输入搜索关键词</div> : null}
      {conditions.keyword && !loading && !contacts.length ? (
        <div styleName="tips">未搜索到联系人</div>
      ) : null}
    </main>

    <AnyTransfer item={transfering} onFinish={transferFinish} />
  </div>
}

function QywxSelect(props: {
  qywxs: AccountQywx[] | null
  value: string | null
  onChange: (id: string | null) => void
}) {
  const { qywxs, value, onChange } = props

  function renderItem(qywx: AccountQywx) {
    const offline = qywx.status !== AccountQywxStatus.Online
    return <div styleName="qywx-select-item">
      <div styleName="name">{qywx.friendlyFullName}</div>
      {offline ? <Tag>离线</Tag> : null}
    </div>
  }

  const options = qywxs
    ? [
        { label: '全部', name: '全部', value: '' },
        ...qywxs.map(qywx => ({
          label: renderItem(qywx),
          name: qywx.friendlyFullName,
          value: qywx.wxid,
        })),
      ]
    : [{ label: '加载中', name: '', value: '' }]

  return <Select
    styleName="qywx-select"
    disabled={!qywxs}
    value={value ?? ''}
    onChange={value => onChange(value || null)}
    showSearch
    options={options}
    optionFilterProp="name"
  ></Select>
}

function TagSelect(props: {
  tags: SearchTag[] | null
  value: string | null
  onChange: (id: string | null) => void
}) {
  const { tags, value, onChange } = props

  function renderItem(tag: SearchTag) {
    return <div styleName="tag-select-item">
      <div styleName="name">{tag.name}</div>
      <div styleName="corp">{tag.corpname}</div>
    </div>
  }

  const options = tags
    ? [
        { label: '全部', name: '全部', value: '' },
        ...tags.map(tag => ({ label: renderItem(tag), name: tag.name, value: tag.id })),
      ]
    : [{ label: '加载中', name: '', value: '' }]

  return <Select
    styleName="tag-select"
    disabled={!tags}
    value={value ?? ''}
    onChange={value => onChange(value || null)}
    showSearch
    options={options}
    optionFilterProp="name"
  ></Select>
}

function SearchContact(props: {
  contact: FullSearchContact
  qywx: AccountQywx | null
  startTransfer: () => void
}) {
  const { contact, qywx, startTransfer } = props

  const online = !!qywx && qywx.status === AccountQywxStatus.Online

  return <div styleName="contact">
    <img styleName="avatar" loading="lazy" src={contact.avatar || defaultAvatar} />
    <div styleName="main">
      <div styleName="name">
        <span>
          {contact.remark ? (
            <>
              {contact.remark}
              <span styleName="tip-name">{contact.name}</span>
            </>
          ) : (
            contact.name
          )}
        </span>
      </div>
      {!qywx ? null : (
        <div styleName="owner">
          <div styleName="owner-name">{qywx.friendlyFullName}</div>
          {!online ? <Tag>离线</Tag> : null}
        </div>
      )}
    </div>
    <div styleName="tags">{contact.tagNames.map((name, i) => <Tag key={i}>{name}</Tag>)}</div>
    {online ? <Button onClick={startTransfer}>发起聊天</Button> : null}
  </div>
}
